package com.yanqu.road.entity.activity.selectlottery.config;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.selectlottery.enums.SelectLotteryBdTypeEnum;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SelectLotteryConfig {

    /**
     * 活动信息
     */
    private ActivityInfo activityInfo;

    /**
     * config map
     */
    private Map<String, ActivityConfig> activityConfigMap;

    /**
     * 道具配置表
     */
    private Map<Integer, SelectLotteryGoodsConfig> goodsConfigMap;

    //抽取消耗（道具id=数量）
    public Property SELECT_LOTTERY_EXTRACT_COST;

    //稀有奖励概率
    public List<List<Integer>> SELECT_LOTTERY_RARE_WEIGHT_PARAM;
    private int hitSelectRewardDrawNum = 100;//必中自选奖励最大抽奖次数

    //公告 数量
    public int SELECT_LOTTERY_EXTRACT_NOTICE_NUM;

    //小保底需要抽数
    public int ROLL_GUARANTEE_NUM;

    //小保底抽奖参数（lottery表id,权重|lottery表id,权重）
    public Map<Integer, Integer> ROLL_GUARANTEE_PARAM;

    //第x次小保底是大保底
    public int ROLL_BIG_GUARANTEE_TIMES;


    public SelectLotteryConfig(ActivityInfo activityInfo, Map<String, ActivityConfig> activityConfigMap, Map<Integer, SelectLotteryGoodsConfig> goodsConfigMap) {
        this.activityInfo = activityInfo;
        this.activityConfigMap = activityConfigMap;
        this.goodsConfigMap = goodsConfigMap;
        //解析config
        this.parseActivityConfig(activityConfigMap);
    }

    /**
     * 解析config
     */
    private void parseActivityConfig(Map<String, ActivityConfig> activityConfigMap) {
        //抽取消耗（道具id=数量）
        ActivityConfig lotteryExtractCost = activityConfigMap.get("SELECT_LOTTERY_EXTRACT_COST");
        this.SELECT_LOTTERY_EXTRACT_COST = lotteryExtractCost == null ? null : PropertyHelper.parseStringToProperty(lotteryExtractCost.getValue());
        //稀有奖励概率
        ActivityConfig lotteryRareWeightParam = activityConfigMap.get("SELECT_LOTTERY_RARE_WEIGHT_PARAM");
        this.SELECT_LOTTERY_RARE_WEIGHT_PARAM = new ArrayList<>();
        if (lotteryRareWeightParam != null) {
            List<String> lotteryRareWeightParamList = StringUtils.stringToStringList(lotteryRareWeightParam.getValue(), "\\|");
            for (String item : lotteryRareWeightParamList) {
                List<Integer> weightList = StringUtils.stringToIntegerList(item, ";");
                this.SELECT_LOTTERY_RARE_WEIGHT_PARAM.add(weightList);
            }
        }
        List<Integer> lastWeightConfig = this.SELECT_LOTTERY_RARE_WEIGHT_PARAM.get(this.SELECT_LOTTERY_RARE_WEIGHT_PARAM.size() - 1);
        this.hitSelectRewardDrawNum = lastWeightConfig.get(0);
        //PVP公告 数量
        ActivityConfig lotteryExtractNoticeNum = activityConfigMap.get("SELECT_LOTTERY_EXTRACT_NOTICE_NUM");
        this.SELECT_LOTTERY_EXTRACT_NOTICE_NUM = lotteryExtractNoticeNum == null ? 50 : lotteryExtractNoticeNum.getIntValue();

        ActivityConfig rollGuaranteeNum = activityConfigMap.get("ROLL_GUARANTEE_NUM");
        this.ROLL_GUARANTEE_NUM = rollGuaranteeNum == null ? 20 : rollGuaranteeNum.getIntValue();

        ActivityConfig rollGuaranteeParam = activityConfigMap.get("ROLL_GUARANTEE_PARAM");
        Map<Integer, Integer> rollGuaranteeParamMap = new HashMap<>();
        if (rollGuaranteeParam != null && !StringUtils.isNullOrEmpty(rollGuaranteeParam.getValue())) {
            String[] params = rollGuaranteeParam.getValue().split("\\|");
            for (String param : params) {
                String[] paramArr = param.split(";");
                rollGuaranteeParamMap.put(Integer.valueOf(paramArr[0]), Integer.valueOf(paramArr[1]));
            }
        }
        this.ROLL_GUARANTEE_PARAM = rollGuaranteeParamMap;

        ActivityConfig rollBigGuaranteeTimes = activityConfigMap.get("ROLL_BIG_GUARANTEE_TIMES");
        this.ROLL_BIG_GUARANTEE_TIMES = rollBigGuaranteeTimes == null ? 4 : rollBigGuaranteeTimes.getIntValue();
    }

    public int getHitSelectRewardDrawNum() {
        return hitSelectRewardDrawNum;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public Map<String, ActivityConfig> getActivityConfigMap() {
        return activityConfigMap;
    }

    public Map<Integer, SelectLotteryGoodsConfig> getGoodsConfigMap() {
        return goodsConfigMap;
    }

    public SelectLotteryGoodsConfig getGoodsConfig(int goodsId) {
        return this.goodsConfigMap.get(goodsId);
    }

    /**
     * 是否命中自选奖励
     * @param reHitDrawNum
     * @return
     */
    public boolean isHitSelectReward(int reHitDrawNum) {
        int targetWeight = 0;
        for (List<Integer> item : this.SELECT_LOTTERY_RARE_WEIGHT_PARAM) {
            int drawNum = item.get(0);
            int weight = item.get(1);
            if (reHitDrawNum >= drawNum) {
                targetWeight = weight;
            }
        }
        int randoWeight = RandomHelper.rand1000();
        if (targetWeight > randoWeight) {
            return true;
        }
        return false;
    }

    /**
     * 是否中必中保底
     * @param drawNum
     * @param seRewardNum
     * @return
     */
    public SelectLotteryBdTypeEnum isHitGuarantee(int drawNum, int seRewardNum) {
        //剩余必中保底抽取次数
        if (drawNum >= this.ROLL_GUARANTEE_NUM) {
            //中保底,判断是中大保底还是小保底
            if (seRewardNum >= this.ROLL_BIG_GUARANTEE_TIMES) {
                //中大保底
                return SelectLotteryBdTypeEnum.BIG;
            } else {
                //中小保底
                return SelectLotteryBdTypeEnum.SMALL;
            }
        }
        return SelectLotteryBdTypeEnum.NOT;
    }

    /**
     * 权重获取小保底奖励ID
     * @return
     */
    public int getSecondRewardId() {
        return RandomHelper.getRandomKeyByWeight(this.ROLL_GUARANTEE_PARAM);
    }

    /**
     * 随机普通奖励
     * @return
     */
    public int randomNormalReward() {
        Map<Integer, Integer> wMap = new HashMap<>();
        for (SelectLotteryGoodsConfig goodsConfig : this.goodsConfigMap.values()) {
            if (goodsConfig.getSelectNum() <= 0) {
                //普通奖励
                wMap.put(goodsConfig.getId(), goodsConfig.getWeights());
            }
        }
        return RandomHelper.getRandomKeyByWeight(wMap);
    }
}
